#include <iostream>
#include <cstring>

#define NAMESIZE 256

using namespace std;

class Person {
	protected:
		char *m_name;
		int m_age;
	public:
		Person(const char *name, int age);
		~Person();
		void setName(const char *name);
		void setAge(int age);
		virtual void show();
		virtual double getSalary() = 0;
};

class Worker : public Person {
	private:
		int m_score;
	public:
		Worker(const char *name, int age, int score);
		Worker(const Worker &w);
		void setScore(int score);
		virtual void show();
		virtual double getSalary();
};

Person::Person(const char *name, int age) : m_age(age)
{
	m_name = new char[NAMESIZE];
	strncpy(m_name, name, NAMESIZE);
}

Person::~Person()
{
	cout << "Person '" << m_name << "' destructed" << endl;
	delete m_name;
	m_name = nullptr;
}

Worker::Worker(const char *name, int age, int score) : Person(name, age), m_score(score)
{
	
}

Worker::Worker(const Worker &w) : Person(w.m_name, w.m_age), m_score(w.m_score)
{
	
}

void Person::show()
{
	cout << "[Person] Name: " << m_name << ", Age: " << m_age << endl;
}

void Worker::show()
{
	cout << "[Worker] Name: " << m_name << ", Age: " << m_age << ", Score: " << m_score << endl;
}

void Person::setName(const char *newName)
{
	memset(m_name, '\0', NAMESIZE);
	strncpy(m_name, newName, NAMESIZE);
}

void Person::setAge(int newAge)
{
	m_age = newAge;
}

void Worker::setScore(int newScore)
{
	m_score = newScore;
}

double Worker::getSalary()
{
	return 1000;
}

void showPerson(Person *p)
{
	p->show();
}

int main(void)
{
	Worker w1("Alice", 20, 98);
	Worker w2(w1);

	w2.setName("Bob");
	w2.setAge(22);
	w2.setScore(86);

	showPerson(&w1);
	showPerson(&w2);

	cout << w1.getSalary() << endl;

	return 0;
}

